package com.xiaotu.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.xiaotu.constant.VerifyCodeType;
import com.xiaotu.mapper.LevelRuleMapper;
import com.xiaotu.mapper.PlayerEquipmentMapper;
import com.xiaotu.mapper.PlayerImageMapper;
import com.xiaotu.mapper.PlayerMapper;
import com.xiaotu.model.LevelRuleModel;
import com.xiaotu.model.PlayerEquipmentModel;
import com.xiaotu.model.PlayerModel;
import com.xiaotu.model.VerifyCodeInfoModel;
import com.xiaotu.service.PlayerService;
import com.xiaotu.service.VerifyCodeInfoService;
import com.xiaotu.util.Constants;
import com.xiaotu.util.RegexUtils;
import com.xiaotu.vo.PlayerInfoVo;
import kohgylw.kcnamer.core.KCNamer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.List;

/**
 * @author zhangxiao
 * @create 2021-10-15 13:56
 */
@Service
@Transactional
public class PlayerServiceImpl implements PlayerService {

    @Autowired
    private PlayerMapper playerMapper;

    @Autowired
    private PlayerImageMapper playerImageMapper;

    @Autowired
    private VerifyCodeInfoService verifyCodeInfoService;

    @Autowired
    private KCNamer kcNamer;

    @Autowired
    private PlayerEquipmentMapper playerEquipmentMapper;

    @Autowired
    private LevelRuleMapper levelRuleMapper;

    @Override
    public void updateBattleStatus(Integer playerId, Integer battleStatus) {
        PlayerModel playerModel = new PlayerModel();
        playerModel.setPlayerId(playerId);
        playerModel.setBattleStatus(battleStatus);
        playerMapper.updateByPrimaryKeySelective(playerModel);
    }

    @Override
    public void batchUpdateBattleStatus(List<Integer> playerIds, Integer battleStatus) {
        playerMapper.batchUpdateBattleStatus(playerIds, battleStatus);
    }

    @Override
    public void register(String phone) {
        PlayerModel playerModel = new PlayerModel();
        playerModel.setPhone(phone);
        //默认为一级
        playerModel.setLevel(1);
        playerModel.setBattleStatus(1);
        //注册玩家
        playerMapper.insertSelective(playerModel);
        //设置指定手机号的所有验证码为无效
        verifyCodeInfoService.inValidPhoneCode(phone, VerifyCodeType.LoginOrRegister.getValue());
        //添加装备
        PlayerEquipmentModel playerEquipmentModel = new PlayerEquipmentModel();
        playerEquipmentModel.setPlayerId(playerModel.getPlayerId());
        playerEquipmentMapper.insertSelective(playerEquipmentModel);
    }

    @Override
    public void checkRegistPlayer(String phone, String verifyCode) {
        //校验手机号是否合法
        if (StrUtil.isBlank(phone))
            throw new IllegalArgumentException("请填写手机号");
        if (!RegexUtils.regexFind(Constants.REGEX_PHONE_NUMBER, phone))
            throw new IllegalArgumentException("手机号不合法");
        //校验手机号验证码是否匹配
        if (ObjectUtil.isNull(verifyCode))
            throw new IllegalArgumentException("请填写短信验证码");
        VerifyCodeInfoModel validInfoModel = verifyCodeInfoService.queryByPhoneAndCode(phone, verifyCode, VerifyCodeType.LoginOrRegister.getValue());
        if (ObjectUtil.isNull(validInfoModel))
            throw new IllegalArgumentException("验证码错误");
        Example example = new Example(PlayerModel.class);
        example.createCriteria().andEqualTo("phone", phone);
        if (playerMapper.selectCountByExample(example) > 0)
            throw new IllegalArgumentException("手机号已注册");
    }

    @Override
    public boolean validNickName(String phone, String nickName) {
        Example example = new Example(PlayerModel.class);
        example.createCriteria().andEqualTo("playerName", nickName).andNotEqualTo("phone", phone);
        if (playerMapper.selectCountByExample(example) > 0)
            return false;
        return true;
    }

    @Override
    public void setNickName(String phone, String nickName) {
        PlayerModel playerModel = new PlayerModel();
        playerModel.setPlayerName(nickName);
        Example example = new Example(PlayerModel.class);
        example.createCriteria().andEqualTo("phone", phone);
        playerMapper.updateByExampleSelective(playerModel, example);
    }

    @Override
    public String refreshNickName() {
        while (true) {
            Example example = new Example(PlayerModel.class);
            String randomName = kcNamer.getRandomName();
            example.createCriteria().andEqualTo("playerName", randomName);
            if (playerMapper.selectCountByExample(example) == 0) {
                return randomName;
            }
        }
    }

    @Override
    public PlayerInfoVo getPlayerInfo(Integer playerId) {
        Example example = new Example(PlayerModel.class);
        example.createCriteria().andEqualTo("playerId", playerId);
        example.selectProperties("imageId", "playerName", "phone", "level");
        PlayerModel mo = playerMapper.selectOneByExample(example);
        PlayerInfoVo vo = new PlayerInfoVo();
        if (ObjectUtil.isNotNull(mo.getImageId()))
            vo.setImageUrl(playerImageMapper.selectByPrimaryKey(mo.getImageId()).getImageUrl());
        PlayerEquipmentModel playerEquipmentModel = playerEquipmentMapper.selectByPrimaryKey(playerId);
        vo.setGoldCoins(playerEquipmentModel.getGoldCoins());
        LevelRuleModel levelRuleModel = levelRuleMapper.selectByPrimaryKey(mo.getLevel());
        vo.setLevelRuleValue(levelRuleModel.getLevelRuleId());
        vo.setLevelRuleName(levelRuleModel.getLevelRuleName());
        BeanUtil.copyProperties(mo, vo);
        return vo;
    }

    @Override
    public void changeImage(Integer playerId, Integer imageId) {
        PlayerModel mo = new PlayerModel();
        mo.setPlayerId(playerId);
        mo.setImageId(imageId);
        playerMapper.updateByPrimaryKeySelective(mo);
    }

    @Override
    public void authentication(Integer playerId) {
        PlayerModel playerModel = new PlayerModel();
        playerModel.setPlayerId(playerId);
        playerModel.setAuthStatus(1);
        playerMapper.updateByPrimaryKeySelective(playerModel);
    }

    @Override
    public void setPlayerBattleStatus(Integer playerId, Integer battleStatus) {
        PlayerModel playerModel = new PlayerModel();
        playerModel.setPlayerId(playerId);
        playerModel.setBattleStatus(battleStatus);
        playerMapper.updateByPrimaryKeySelective(playerModel);
    }

}
